﻿using System.ComponentModel;
using System.Reflection;

namespace System.NETool;

/// <summary>
/// 提供枚举类型的扩展方法
/// </summary>
public static class EnumEx
{
    /// <summary>
    /// 将字符串转换为枚举类型
    /// </summary>
    /// <typeparam name="TEnum">枚举类型</typeparam>
    /// <param name="this">要转换的字符串</param>
    /// <param name="ignoreCase">是否忽略大小写</param>
    /// <returns>转换后的枚举类型</returns>
    public static TEnum ToEnum<TEnum>(this string @this, bool ignoreCase = true) where TEnum : Enum
    {
        return @this.InEnum<TEnum>()() ? default : (TEnum)Enum.Parse(typeof(TEnum), @this, ignoreCase);
    }

    /// <summary>
    /// 判断字符串是否为枚举类型的有效值
    /// </summary>
    /// <typeparam name="TEnum">枚举类型</typeparam>
    /// <param name="this">要检查的字符串</param>
    /// <returns>如果字符串是有效的枚举值，则返回 false；否则返回 true</returns>
    public static Func<bool> InEnum<TEnum>(this string @this) where TEnum : Enum
    {
        return () => string.IsNullOrEmpty(@this) || !Enum.IsDefined(typeof(TEnum), @this);
    }

    /// <summary>
    /// 获取枚举类型的所有值
    /// </summary>
    /// <typeparam name="T">枚举类型</typeparam>
    /// <returns>枚举类型的所有值的列表</returns>
    public static List<int> GetValues<T>() where T : Enum
    {
        return Enum.GetValues(typeof(T)).Cast<int>().ToList();
    }

    /// <summary>
    /// 获取枚举字段的描述
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>描述字符串</returns>
    public static string Description(this Enum @this)
    {
        // 获取枚举字段信息
        FieldInfo info = @this.GetType().GetField(@this.ToString());
        if (info == null) return string.Empty;

        // 获取 DescriptionAttribute 特性
        var attribute = info.GetCustomAttribute<DescriptionAttribute>();

        // 返回描述，如果没有 DescriptionAttribute 则返回枚举值的字符串表示
        return attribute?.Description ?? @this.ToString();
    }

    /// <summary>
    /// 获取枚举的整数值
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>枚举的整数值</returns>
    public static int Value(this Enum @this)
    {
        return @this.GetHashCode();
    }

    /// <summary>
    /// 获取枚举的无符号短整型值
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>枚举的无符号短整型值</returns>
    public static ushort UShortValue(this Enum @this)
    {
        return (ushort)@this.Value();
    }

    /// <summary>
    /// 获取枚举的字节值
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>枚举的字节值</returns>
    public static byte ByteValue(this Enum @this)
    {
        return (byte)@this.Value();
    }

    /// <summary>
    /// 获取枚举的短整型值
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>枚举的短整型值</returns>
    public static short ShortValue(this Enum @this)
    {
        return (short)@this.Value();
    }

    /// <summary>
    /// 获取枚举的无符号整数值
    /// </summary>
    /// <param name="this">枚举值</param>
    /// <returns>枚举的无符号整数值</returns>
    public static uint UIntValue(this Enum @this)
    {
        return (uint)@this.Value();
    }
}
